<template>
  <div>
    <el-input
      ref="categorySelect"
      v-model="categoryNames"
      placeholder="请选择分类"
      @focus="showCategoryDialog"
      suffix-icon="el-icon-search"
      @change="handleChange"
    />
    <basic-dialog
      :visible="dialogVisible"
      :title="title"
      :top="'8vh'"
      :show-footer="false"
      :width="'85%'"
      :handleClose="handleCloseDialog"
      :handleOpen="handleOpenDialog"
    >
      <el-row>
        <el-col :span="12" class="left-col">
          <div class="category-search">
            <el-form size="mini" ref="formData" :model="formData" inline>
              <el-form-item prop="categoryName" label="名称">
                <el-input
                  placeholder="请输入品类名称"
                  v-model="formData.categoryName"
                  @keyup.enter.native="handleSerach"
                ></el-input>
              </el-form-item>
              <el-form-item prop="categoryName" label="编码">
                <el-input
                  placeholder="请输入四级类编码"
                  v-model="formData.categoryNo"
                  @keyup.enter.native="handleSerach"
                ></el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="handleSerach">查询</el-button>
              </el-form-item>
            </el-form>
          </div>
          <el-divider class="divider" content-position="left">条件查询结果：</el-divider>
          <div class="category-searchlist">
            <el-checkbox-group v-model="searchList.checkList" v-loading="searchLoading">
              <el-checkbox
                v-for="item in searchList.dataSource"
                :label="item.categoryUuid"
                :key="item.categoryUuid"
                @change="(val) => { handleCheckSearchList(val, item) }"
              >
              {{ item.categoryPath }}&nbsp;&nbsp;{{ item.categoryNo }}
              </el-checkbox>
            </el-checkbox-group>
          </div>
          <el-divider class="divider" content-position="left">品类树选择：</el-divider>
          <div class="category-tree">
            <el-tree
              v-loading="categoryTree.loading"
              ref="categoryTree"
              show-checkbox
              highlight-current
              :check-strictly="checkStrictly"
              :data="categoryTree.dataSource"
              :node-key="categoryTree.nodeKey"
              :props="categoryTree.props"
              @check="getCheckedNodes">
            </el-tree>
          </div>
        </el-col>
        <el-col :span="12">
          <div class="selected-card">
            <div>
              <span>已选品类</span>
              <div style="float: right;">
                <el-button
                  v-show="selectCategoryList.length"
                  type="text"
                  @click="handleClear"
                >一键清空</el-button>
                <el-button
                  type="text"
                  @click="handleConfirm"
                >确定</el-button>
              </div>
            </div>
            <el-divider class="divider" />
            <el-tag
              class="category-tag"
              v-for="tag in selectCategoryList"
              :key="tag.categoryUuid"
              closable
              :disable-transitions="false"
              effect="plain"
              @close="handleRemoveCategory(tag, true)">
              <span class="tag-text">{{tag.categoryPath}} {{tag.categoryNo}}</span>
            </el-tag>
          </div>
        </el-col>
      </el-row>
    </basic-dialog>
  </div>
</template>
<script>
import BasicDialog from '@/components/BasicDialog'
import {
  queryCategoryByNoOrNameService,
  queryAllCategoryService
} from '@/api/public'

export default {
  name: 'SelectCategory',
  components: {
    BasicDialog,
  },
  props: {
    dialogTitle: {
      type: String,
      default: '选择品类'
    },
    checkStrictly: {
      type: Boolean,
      default: false
    },
    disabledLevel: {
      type: Array,
      default: () => [1, 2, 3]
    }
  },
  data () {
    return {
      categoryNames: '',
      dialogVisible: false,
      searchLoading: false,
      selectCategoryList: [], // 已选品类集合
      searchCategoryList: [], // 条件查询选择集合
      treeCategoryList: [], // 品类树选择集合
      categoryTree: {
        loading: false,
        dataSource: [],
        props: {
          children: 'children',
          label: 'categoryNameAndNoStr',
          disabled: data => this.disabledLevel.includes(data.levelNum >> 0)
        },
        nodeKey: 'categoryNo',
      },
      formData: {
        categoryName: '',
        categoryNo: '',
      },
      searchList: {
        dataSource: [], // 数据源
        checkList: [], // 勾选对象
      },
    };
  },
  computed: {
    // 弹窗标题
    title () {
      return this.dialogTitle
    }
  },
  watch: {
    searchCategoryList: {
      handler (val) {
        this.generateLinkData()
      },
      deep: true
    },
    treeCategoryList: {
      handler (val) {
        this.generateLinkData()
      },
      deep: true
    },
  },
  methods: {
    // 名称编码查询分类
    async handleSerach () {
      if (Object.values(this.formData).every(item => !item)) {
        return this.$message.warning('品类名称和品类编码不能同时为空');
      }
      const res = await queryCategoryByNoOrNameService(this.formData, state => (this.searchLoading = state))
      if (res) {
        this.searchList.checkList = [];
        this.searchList.dataSource = res.retData;
      }
    },
    // 查询分类树
    async getAllCategory () {
      const res = await queryAllCategoryService({}, state => (this.categoryTree.loading = state))
      if (res) {
        this.categoryTree.dataSource = res.retData || []
      }
    },
    // 分类查询结果列表勾选
    handleCheckSearchList (val, data) {
      if (val) {
        if (this.searchCategoryList.some(item => item.categoryUuid == data.categoryUuid)) {
          return;
        }
        this.searchCategoryList.push(data)
      } else {
        this.handleRemoveCategory(data)
      }
    },
    // 树节点勾选
    getCheckedNodes () {
      const checkedNodes = this.$refs.categoryTree.getCheckedNodes()
      const level4List = this.checkStrictly ? checkedNodes : checkedNodes.filter(item => item.levelNum == 4)
      this.treeCategoryList = _.uniqBy(level4List, this.categoryTree.nodeKey)
    },
    // 取消品类选择
    handleRemoveCategory (data, isTag) {
      this.searchCategoryList = this.searchCategoryList.filter(item => item.categoryUuid != data.categoryUuid)
      this.treeCategoryList = this.treeCategoryList.filter(item => item.categoryUuid != data.categoryUuid)
      if (isTag) {
        this.searchList.checkList = this.searchList.checkList.filter(item => item != data.categoryUuid)
        this.$refs.categoryTree.setChecked(data[this.categoryTree.nodeKey], false);
      }
    },
    // 清空选择结果
    handleClear () {
      const content = `确定后将清空所有已选${this.checkStrictly ? '分类' : '四级分类'}，您确认吗？`
      this.$confirm(content, '清空', {
        type: 'warning',
      }).then(() => {
        this.handleClearCategory()
      }).catch(() => {});
    },
    // 组合已关联数据
    generateLinkData () {
      this.selectCategoryList = _.uniqBy(this.searchCategoryList.concat(this.treeCategoryList), this.categoryTree.nodeKey)
    },
    // 确定
    handleConfirm () {
      this.categoryNames = this.selectCategoryList.map(item => item.categoryName).join(',')
      this.$emit('selectCategoryCallback', this.selectCategoryList)
      this.dialogVisible = false
    },
    // 清空弹框内容
    handleClearCategory () {
      this.searchCategoryList = []; // 条件查询结果
      this.searchList.checkList = []; // 查询条件勾选结果
      this.treeCategoryList = []; // 品类树勾选结果
      this.clearAllCheckedNodes(); // 清空品类树勾选
      this.closeAllExpandNodes(); // 关闭品类树展开状态
      this.searchList.dataSource = [];
      // eslint-disable-next-line no-unused-expressions
      this.$refs?.formData?.resetFields()
    },
    // 清空所有已勾选节点的勾选状态
    clearAllCheckedNodes () {
      // eslint-disable-next-line no-unused-expressions
      this.$refs?.categoryTree?.setCheckedKeys([]);
    },
    // 关闭所有已展开节点
    closeAllExpandNodes () {
      var nodes = this.$refs?.categoryTree?.store?.nodesMap;
      for (let i in nodes) {
        nodes[i].expanded = false;
      }
    },
    // 打开弹窗
    handleOpenDialog () {
      this.getAllCategory();
    },
    // 关闭弹框
    handleCloseDialog () {
      this.dialogVisible = false
      if (!this.categoryNames) {
        this.handleClearCategory()
      }
    },
    showCategoryDialog () {
      this.dialogVisible = true;
    },
    handleChange (val) {
      // this.$refs['categoryPannel'].clearCheckedNodes();
    },
    // 清空查询条件
    clearSelectResult () {
      this.categoryNames = ''
      this.handleClearCategory()
    }
  }
};
</script>
<style lang="less" scoped>
.divider {
  margin: 10px 0;
}
.left-col {
  border-right: 1px dashed #dadada;
  padding-right: 20px;
}
.category-searchlist {
  .el-checkbox-group {
    border: 1px solid #ebeef5;
    padding-left: 5px;
    height: 200px;
    max-height: 200px;
    overflow-y: auto;
    label {
      line-height: 24px;
      &:first-child {
        margin-top: 10px;
      }
      &:last-child {
        margin-bottom: 10px;
      }
    }
  }
}
/deep/ .category-tree {
  height: 400px !important;
  overflow: auto;
  margin: 10px 0px;
  border: 1px solid #ebeef5;
}
.category-tag {
  margin: 5px 0;
  .tag-text {
    display: inline-block;
    width: 440px;
  }
}
.selected-card {
  padding: 10px;
  margin-left: 10px;
  max-height: 700px;
  overflow: auto;
}
</style>
